package cn.backflow.admin.common.interceptor;

import cn.backflow.lib.util.JsonMap;
import cn.backflow.lib.util.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 系统全局异常处理器
 * Created by Nandy on 2016/6/23.
 */
@ControllerAdvice
public class GlobalExceptionHandler extends ExceptionHandlerExceptionResolver {
    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 捕获所有SpringMVC绑定参数缺失错误
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ModelAndView handleMissingServletRequestParameterException(HttpServletRequest req, HttpServletResponse res, Exception e) {
        return handleException(req, res, e);
    }


    /**
     * 捕获所有系统内部错误, 如404等
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(Throwable.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest req, HttpServletResponse res, Exception e) {
        return handleException(req, res, e);
    }

    /**
     * 捕获所系统内部错误
     */
    @Override
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse res, Object o, Exception e) {
        return handleException(req, res, e);
    }

    /**
     * 处理错误的总入口
     */
    private ModelAndView handleException(HttpServletRequest req, HttpServletResponse res, Exception e) {
        JsonMap json = JsonMap.fail(e.getCause().getLocalizedMessage());

        logger.error("GlobalExceptionHandler", e);

        res.setStatus(500);
        if (e instanceof MissingServletRequestParameterException) {
            res.setStatus(500);
            json.msg("缺少请求参数!");
        }
        if (e instanceof NoHandlerFoundException) {
            res.setStatus(404);
            json.msg("您请求的地址不存在或没有访问权限!");
        }
        if (e instanceof UnauthorizedException) {
            res.setStatus(401);
            json.msg("您没有该功能的操作权限!");
        }

        return new ModelAndView(new MappingJackson2JsonView(JsonUtil.mapper), json);
    }
}
